package dbops

import (
	_ "database/sql"
	"fmt"
	"gitee.com/DengAnbang/Wefore/src/bean"
	"gitee.com/DengAnbang/Wefore/src/code"
	"gitee.com/DengAnbang/Wefore/src/push"
	"gitee.com/DengAnbang/goutils/dbutils"
	"gitee.com/DengAnbang/goutils/loge"
	"gitee.com/DengAnbang/goutils/utils"
	"path"
	"strings"
)

type FileBean struct {
	Id                   string `json:"-"`
	FileId               string `json:"file_id"`
	FileName             string `json:"file_name"`
	FilePath             string `json:"file_path"`
	WorkTime             int    `json:"work_time"`
	CommissionedUserId   string `json:"commissioned_user_id"`
	CommissionedUserName string `json:"commissioned_user_name"`
}

func NewFileBean(data map[string]string) FileBean {
	return FileBean{
		Id:                   data["id"],
		FileName:             data["file_name"],
		FilePath:             data["file_path"],
		FileId:               data["file_id"],
		CommissionedUserId:   data["commissioned_user_id"],
		CommissionedUserName: data["name"],
		WorkTime:             utils.String2int(data["work_time"], 0),
	}
}

type Commissioned struct {
	UserId     string `json:"user_id"`
	UserName   string `json:"user_name"`
	ToUserId   string `json:"to_user_id"`
	ToUserName string `json:"to_user_name"`
	Created    string `json:"created"`
}

func NewCommissioned(data map[string]string) Commissioned {
	return Commissioned{
		UserId:     data["user_id"],
		UserName:   data["user_name"],
		ToUserId:   data["to_user_id"],
		ToUserName: data["to_user_name"],
		Created:    data["commissionedCreated"],
	}
}

type FileTreeBean struct {
	bean.TreeBean
}

func NewFileTreeBean(data map[string]string) FileTreeBean {
	return FileTreeBean{
		TreeBean: bean.NewTreeBean(data),
	}
}

//创建文件夹，如果nodeParentId==0，则表示根文件夹，isNewUUID表示是否新建id,false userId就会被当成uuid
func FileTreeNodeCreate(userId, nodeName, nodeParentId string, isNewUUID bool) (FileTreeBean, error) {
	var treeBean = FileTreeBean{}
	treeBean.NodeName = nodeName
	treeBean.NodeParentId = nodeParentId
	var depth = 0
	if len(userId) == 0 {
		return treeBean, bean.NewErrorMessage("创建人ID不能为空")
	}
	if len(nodeName) == 0 {
		return treeBean, bean.NewErrorMessage("名称不能为空")
	}
	uuid := ""
	if isNewUUID {
		uuid = utils.NewUUID()
	} else {
		uuid = userId
	}
	if nodeParentId != "0" {
		treeParentBean, err := FileTreeNodeSelect(nodeParentId)
		if err != nil {
			return treeBean, err
		}
		depth = treeParentBean.Depth + 1
	}
	stmtIn, err := dbConn.Prepare("INSERT INTO table_tree_file (node_id,node_name,node_parent_id,depth)VALUES(?,?,?,?)")
	if err != nil {
		return treeBean, err
	}
	_, err = stmtIn.Exec(uuid, nodeName, nodeParentId, depth)
	if err != nil {
		return treeBean, err
	}
	_ = stmtIn.Close()
	treeBean.Depth = depth
	treeBean.NodeId = uuid
	loge.WD(bean.NewSucceedMessage(treeBean).GetJson())
	return treeBean, nil
}

//todo 递归删除(待优化)
func FileTreeNodeDeleteAll(nodeId string) error {
	if len(nodeId) == 0 {
		return bean.NewErrorMessage("节点ID不能为空")
	}
	if nodeId == "0" {
		return bean.NewErrorMessage("根节点不能为删除！")
	}
	beans, err := FileTreeChildNodeSelectAll(nodeId)
	if err != nil {
		return err
	}
	beans = append(beans, FileTreeBean{bean.TreeBean{NodeId: nodeId}})
	for _, v := range beans {
		stmtIn, err := dbConn.Prepare("DELETE FROM table_tree_file WHERE node_id=?")
		if err != nil {
			return err
		}
		_, err = stmtIn.Exec(v.NodeId)
		if err != nil {
			return err
		}
		_ = stmtIn.Close()
	}
	return err
}

/**
删除当前一个节点，下级的不会删除
*/
func FileTreeNodeDelete(nodeId string) error {
	if len(nodeId) == 0 {
		return bean.NewErrorMessage("节点ID不能为空")
	}
	if nodeId == "0" {
		return bean.NewErrorMessage("根节点不能为删除！")
	}
	stmtIn, err := dbConn.Prepare("DELETE FROM table_tree_file WHERE node_id=?")
	if err != nil {
		return err
	}
	_, err = stmtIn.Exec(nodeId)
	if err != nil {
		return err
	}
	_ = stmtIn.Close()
	return err
}

//文件节点修改
func FileTreeNodeUpdate(nodeId, nodeName string) error {
	if len(nodeId) == 0 {
		return bean.NewErrorMessage("节点ID不能为空")
	}
	if len(nodeName) == 0 {
		return bean.NewErrorMessage("节点名称不能为空")
	}

	stmtIn, err := dbConn.Prepare("UPDATE  table_tree_file SET node_name=? WHERE node_id=?")
	if err != nil {
		return err
	}
	_, err = stmtIn.Exec(nodeName, nodeId)
	if err != nil {
		return err
	}
	_ = stmtIn.Close()
	return err
}

//查询单个树节点的信息
func FileTreeNodeSelect(nodeId string) (FileTreeBean, error) {
	var fileTreeBean FileTreeBean
	stmtOut, err := dbConn.Prepare("SELECT * FROM table_tree_file WHERE node_id = ?")
	if err != nil {
		return fileTreeBean, err
	}
	defer stmtOut.Close()
	rows, err := stmtOut.Query(nodeId)
	if err != nil {
		return fileTreeBean, err
	}
	defer rows.Close()
	if rows.Next() {
		var stringMap map[string]string
		stringMap, err = dbutils.GetRowsMap(rows)
		if err != nil {
			return fileTreeBean, err
		}
		fileTreeBean = NewFileTreeBean(stringMap)
	}
	return fileTreeBean, err
}

//查询当级所有子节点树节点的信息
func FileTreeChildNodeSelect(nodeId string) ([]FileTreeBean, error) {
	var fileTreeBean = make([]FileTreeBean, 0)
	stmtOut, err := dbConn.Prepare("SELECT * FROM table_tree_file WHERE node_parent_id = ?")
	if err != nil {
		return fileTreeBean, err
	}
	defer stmtOut.Close()
	rows, err := stmtOut.Query(nodeId)
	if err != nil {
		return fileTreeBean, err
	}
	defer rows.Close()
	for rows.Next() {
		var stringMap map[string]string
		stringMap, err = dbutils.GetRowsMap(rows)
		if err != nil {
			return fileTreeBean, err
		}
		fileTreeBean = append(fileTreeBean, NewFileTreeBean(stringMap))
	}
	return fileTreeBean, err
}

//查询所有子节点树节点的信息
//递归查询
func FileTreeChildNodeSelectAll(nodeId string) ([]FileTreeBean, error) {
	//使用递归的方法
	var treeBean = make([]FileTreeBean, 0)
	beans, err := FileTreeChildNodeSelect(nodeId)
	if err != nil {
		return treeBean, err
	}
	treeBean = append(treeBean, beans...)
	for _, v := range beans {
		treeBeans, err := FileTreeChildNodeSelectAll(v.NodeId)
		if err != nil {
			return treeBeans, err
		}
		treeBean = append(treeBean, treeBeans...)
	}
	return treeBean, err
}

//文件上传到文件夹
func FileTreeFileAdd(nodeId string, filePath string, fileId string, workTime string) error {
	if len(filePath) == 0 {
		return bean.NewErrorMessage("filePath不能为空")
	}
	if len(fileId) == 0 {
		return bean.NewErrorMessage("fileId不能为空")
	}
	stmtIn, err := dbConn.Prepare("REPLACE  INTO table_tree_file_file (node_id,file_name,file_path,file_id,work_time)VALUES(?,?,?,?,?)")
	if err != nil {
		return err
	}
	filePath = strings.Replace(filePath, "\\", "/", -1)
	_, fileName := path.Split(filePath)
	_, err = stmtIn.Exec(nodeId, fileName, filePath, fileId, workTime)
	if err != nil {
		return err
	}
	return nil
}

//文件夹里面的文件委托给其他人
func FileTreeFileCommissioned(fileId, filePath, userId, toUserId, workTime string) error {
	stmtIn, err := dbConn.Prepare("UPDATE table_tree_file_file set commissioned_user_id = ? WHERE file_id=?")
	if err != nil {
		return err
	}
	defer stmtIn.Close()
	_, err = stmtIn.Exec(toUserId, fileId)
	if err != nil {
		return err
	}
	_ = stmtIn.Close()
	err = FileTreeFileAdd(toUserId+"wtwj", filePath, fileId, workTime)
	if err != nil {
		return err
	}
	stmtIn, err = dbConn.Prepare("INSERT INTO table_commissioned_flow (file_id,user_id,to_user_id)VALUES(?,?,?)")
	if err != nil {
		return err
	}
	_, err = stmtIn.Exec(fileId, userId, toUserId)
	if err != nil {
		return err
	}
	_ = stmtIn.Close()
	userBean, _ := UserSelectByUserId(userId)
	messageBean := MessageBean{
		ToUserId:       toUserId,
		MessageType:    code.TypePushCommissioned,
		MessageContent: fmt.Sprintf("收到了一条来自%v的委托任务,请到委托文件夹里面查看!", userBean.UserName),
		MessageAppend:  fileId,
	}
	err = MessageCreate(messageBean)
	//推送委托消息
	push.Push(userId, code.TypePushCommissioned, messageBean)
	return nil
}

//文件委托流向查询
func CommissionedFlowSelect(fileId string) ([]Commissioned, error) {
	var commissioneds = make([]Commissioned, 0)
	stmtOut, err := dbConn.Prepare(`SELECT *, 
UNIX_TIMESTAMP(table_commissioned_flow.created) as commissionedCreated ,
u1.name as user_name ,
u1.user_id as user_id ,
u2.user_id as to_user_id ,
u2.name as to_user_name 
FROM table_commissioned_flow 
 LEFT OUTER JOIN table_user u1 ON table_commissioned_flow.user_id=u1.user_id
 LEFT OUTER JOIN table_user u2 ON table_commissioned_flow.to_user_id=u2.user_id
 WHERE file_id = ?`)
	if err != nil {
		return commissioneds, err
	}
	defer stmtOut.Close()
	rows, err := stmtOut.Query(fileId)
	if err != nil {
		return commissioneds, err
	}
	for rows.Next() {
		var stringMap map[string]string
		stringMap, err = dbutils.GetRowsMap(rows)
		if err != nil {
			return commissioneds, err
		}
		commissioneds = append(commissioneds, NewCommissioned(stringMap))
	}
	return commissioneds, nil
}

//文件夹里面的文件查询
func FileTreeFileSelect(nodeId string) ([]FileBean, error) {
	var fileBean = make([]FileBean, 0)
	stmtOut, err := dbConn.Prepare(`SELECT * FROM table_tree_file_file 
 LEFT OUTER JOIN table_user ON table_tree_file_file.commissioned_user_id=table_user.user_id
 WHERE node_id = ?`)
	if err != nil {
		return fileBean, err
	}
	defer stmtOut.Close()
	rows, err := stmtOut.Query(nodeId)
	if err != nil {
		return fileBean, err
	}
	for rows.Next() {
		var stringMap map[string]string
		stringMap, err = dbutils.GetRowsMap(rows)
		if err != nil {
			return fileBean, err
		}
		fileBean = append(fileBean, NewFileBean(stringMap))
	}
	return fileBean, nil
}
